import electronUtils from '~common/electron';
import { VueMountedCycle } from '~common/vue';
import { FilowDirItem as IFilowDirItem, default as Sqlite } from '~sqlite';
import api, { IDirInnerDirInfo, IDirFileInfo, IDirInnerFileInfo } from './api';
import { defineComponent, ref, reactive, Ref, SetupContext, getCurrentInstance, ComponentInternalInstance, watch } from 'vue';

import Viewer from 'viewerjs';
import LvMsgBox from '~component/vue3-element/msgbox';
import { useCreateDirDialog, useDirItemDialog, useRenameDirDialog, useTransferDirDialog, useTransferFileDialog } from './useDialog';

const sqlite: typeof Sqlite = require('~sqlite').default;

export default defineComponent({
    setup(_: unknown, context: SetupContext) {
        const vueMountedCycle = new VueMountedCycle();
        const current = getCurrentInstance() as ComponentInternalInstance;

        const that = new Init(context, current);

        vueMountedCycle.trigger();

        return { that };
    },
});

export class Init {
    context: SetupContext;
    current: ComponentInternalInstance;

    // 选择的目录项
    dirItem: Ref<string> = ref('');
    // 目录项列表
    dirItemList: Ref<IFilowDirItem[]> = ref([]);

    // 选择的目录分类
    dirCasc: Ref<string> = ref('');
    // 目录分类列表
    dirCascList: Ref<IDirInnerDirInfo[]> = ref([]);

    // 目录下的一级资源列表
    fileList!: IDirFileInfo;
    // 是否资源为空
    isEmptyFiles: Ref<boolean> = ref(true);

    // 选择的文件
    selectFiles!: {
        video: string[];
    };

    // 文件大类型列表
    fileType = [
        { title: '图片', name: 'image' },
        { title: '视频', name: 'video' },
        { title: '音频', name: 'audio' },
        { title: 'Excel', name: 'excel' },
        { title: 'PDF', name: 'pdf' },
        { title: '其他', name: 'other' },
    ];

    // 深度文件
    deepFiles: Ref<boolean> = ref(false);
    // 操作模式
    operateMode: Ref<boolean> = ref(false);
    // 简介模式
    summaryMode: Ref<boolean> = ref(false);

    // 需要显示的文件大类型
    fileTypeCheck: Ref<string[]> = ref(['image', 'video']);

    // 提示文本
    tips: Ref<string> = ref('');

    // 保存目录项对话框
    dirItemDialog: ReturnType<typeof useDirItemDialog>;
    // 创建目录对话框
    createDirDialog: ReturnType<typeof useCreateDirDialog>;
    // 重命名目录对话框
    renameDirDialog: ReturnType<typeof useRenameDirDialog>;
    // 转移目录对话框
    transferDirDialog: ReturnType<typeof useTransferDirDialog>;
    // 转移文件对话框
    transferFileDialog: ReturnType<typeof useTransferFileDialog>;

    constructor(context: SetupContext, current: ComponentInternalInstance) {
        this.context = context;
        this.current = current;

        this.dirItemDialog = useDirItemDialog(this);
        this.createDirDialog = useCreateDirDialog(this);
        this.renameDirDialog = useRenameDirDialog(this);
        this.transferDirDialog = useTransferDirDialog(this);
        this.transferFileDialog = useTransferFileDialog(this);

        this.initFileList();
        this.initSelectFiles();

        this.getDirItemList();

        this.watchDeepFilesChange();
    }

    getCurrentDirPath(): string | null {
        if (this.dirCasc.value) {
            return this.dirCasc.value;
        } else if (this.dirItem.value) {
            return this.dirItem.value;
        } else {
            return null;
        }
    }

    /**
     * 监听深度文件变更
     */
    watchDeepFilesChange(): void {
        watch(this.deepFiles, () => {
            this.getDirInnerFiles();
        });
    }

    /**
     * 获取目录项列表
     */
    async getDirItemList() {
        try {
            const resolveInfo = await sqlite.filowDirItem.searchAll();
            if (resolveInfo.data) {
                this.dirItemList.value = resolveInfo.data;
            }
        } catch (e) {
            console.error(e);
        }
    }

    /**
     * 目录项选择变更回调
     */
    async dirItemChange(dirpath: string) {
        try {
            const result = await api.getDirInnerAllFiles({ dirpath });
            if (result.success) {
                this.dirCasc.value = '';
                this.dirCascList.value = result.data?.innerDirs || [];

                this.initSelectFiles();
                await this.getDirInnerFiles(dirpath);
            }
        } catch (e) {
            console.error(e);
        }
    }

    /**
     * 选择目录分类
     */
    async selectDirCasc(dirpath: string) {
        if (dirpath) {
            this.dirCasc.value = dirpath;

            this.initSelectFiles();
            await this.getDirInnerFiles(dirpath);
        }
    }

    /**
     * 目录分类选择变更回调
     */
    dirCascChange(dirpath: string) {
        this.initSelectFiles();
        if (dirpath) {
            this.getDirInnerFiles(dirpath);
        } else {
            this.getDirInnerFiles(this.dirItem.value);
        }
    }

    /**
     * 获取目录下的一级文件资源
     */
    async getDirInnerFiles(dirpath?: string) {
        if (!dirpath) {
            dirpath = this.getCurrentDirPath() || '';
        }
        if (!dirpath) return;

        try {
            const result = await api.getDirInnerFiles({ dirpath, isDeep: this.deepFiles.value });
            if (result.success && result.data) {
                this.fileList.dirs = result.data.dirs;
                this.fileList.files = result.data.files;
                this.fileList.category = result.data.category;

                this.isEmptyFiles.value = result.data.files.length <= 0;
            }
        } catch (e) {
            console.error(e);
        }
    }

    /**
     * 查看图片
     */
    viewImage(index: number) {
        const image = document.querySelector(`.main-wrapper .image-collapse .image-item-${index} img`);
        if (image) {
            const viewer = new Viewer(image as HTMLElement, {
                inline: false,
                button: false,
                viewed() {
                    // viewer.zoomTo(0.4);
                },
            });
            viewer.show();
        }
    }

    /**
     * 删除目录项
     */
    async dirItemDelete(item: IFilowDirItem) {
        try {
            const result = await sqlite.filowDirItem.delete(item.id);
            if (result.deleteRecord) {
                this.dirItem.value = '';
                this.dirCasc.value = '';
                this.dirCascList.value = [];

                this.initFileList();
                this.initSelectFiles();

                await this.getDirItemList();
            }
        } catch (e) {
            console.error(e);
        }
    }

    dirOperateCommand(command: 'openDir' | 'createDir' | 'transferDir' | 'deleteDir' | 'renameDir') {
        this[command]();
    }

    /**
     * 打开文件
     */
    openFile(file: IDirInnerFileInfo) {
        electronUtils.showItemInFolder(file.path);
    }

    /**
     * 同步资源
     */
    syncFiles() {
        this.getDirInnerFiles();
    }

    /**
     * 打开目录
     */
    openDir() {
        const openPath = this.getCurrentDirPath();
        if (openPath) {
            electronUtils.showItemInFolder(openPath);
        }
    }

    /**
     * 创建目录
     */
    createDir() {
        const currentPath = this.getCurrentDirPath();
        if (currentPath) {
            this.createDirDialog.formData.currentPath = currentPath;
            this.createDirDialog.visible.value = true;
        }
    }

    /**
     * 转移目录
     */
    transferDir() {
        const currentPath = this.getCurrentDirPath();
        if (currentPath) {
            const p = currentPath.split(/\/|\\/);
            p.pop();
            this.transferDirDialog.formData.from = p.join('/');
            this.transferDirDialog.visible.value = true;
        }
    }

    /**
     * 重名目录
     */
    renameDir() {
        const currentPath = this.getCurrentDirPath();
        if (currentPath) {
            const p = currentPath.split(/\/|\\/);
            const oldName = p.pop();
            this.renameDirDialog.formData.currentPath = p.join('/');
            this.renameDirDialog.formData.oldName = oldName || '';
            this.renameDirDialog.visible.value = true;
        }
    }

    /**
     * 删除目录
     */
    deleteDir() {
        LvMsgBox.confirm('确定删除该目录吗？', '删除目录', {
            type: 'warning',
        }).then(async () => {
            try {
                this.tips.value = '正在删除目录...';
                const res = await api.deleteFolder({ dirpaths: [this.dirCasc.value] });
                if (res.success) {
                    const res = await api.getDirInnerAllFiles({ dirpath: this.dirItem.value });

                    this.dirCasc.value = '';
                    this.dirCascList.value = res.data?.innerDirs || [];

                    this.initSelectFiles();
                    await this.getDirInnerFiles();
                }
            } catch (e) {
                console.error(e);
            } finally {
                this.tips.value = '';
            }
        });
    }

    fileOperateCommand(command: 'uploadFile' | 'transferFile' | 'deleteFile') {
        this[command]();
    }

    /**
     * 上传文件
     */
    async uploadFile() {
        const currentPath = this.getCurrentDirPath();
        if (currentPath) {
            const result = await electronUtils.showOpenDialog({ type: 'selectFile' });

            if (!result.isCancel && result.paths) {
                let successNum = 0;
                const allLength = result.paths.length;

                this.tips.value = `正在上传文件：${successNum}/${allLength} ...`;

                const promises = result.paths.map(m => {
                    return new Promise((resolve, reject) => {
                        const params = {
                            list: [
                                {
                                    from: m,
                                    to: currentPath,
                                },
                            ],
                        };
                        api.copyFileOrFolder(params)
                            .then(res => {
                                successNum++;
                                this.tips.value = `正在上传文件：${successNum}/${allLength} ...`;
                                resolve(res);
                            })
                            .catch(e => {
                                reject(e);
                            });
                    });
                });

                Promise.allSettled(promises).finally(() => {
                    this.tips.value = `上传文件完毕：${successNum}/${allLength}`;

                    setTimeout(() => {
                        this.tips.value = '';
                    }, 2000);

                    this.initSelectFiles();
                    this.getDirInnerFiles();
                });
            }
        }
    }

    /**
     * 转移文件
     */
    transferFile() {
        const currentPath = this.getCurrentDirPath();
        const allSelectFiles = this.getAllSelectFiles();
        if (currentPath && allSelectFiles.length > 0) {
            this.transferFileDialog.formData.from = currentPath;
            this.transferFileDialog.visible.value = true;
        }
    }

    /**
     * 删除文件
     */
    deleteFile() {
        const allSelectFiles = this.getAllSelectFiles();
        if (allSelectFiles.length > 0) {
            LvMsgBox.confirm('确定删除所选文件吗？', '删除文件', {
                type: 'warning',
            }).then(async () => {
                try {
                    this.tips.value = '正在删除文件...';
                    const res = await api.deleteFile({ filepaths: allSelectFiles });
                    if (res.success) {
                        this.initSelectFiles();
                        const currentPath = this.getCurrentDirPath();
                        if (currentPath) {
                            await this.getDirInnerFiles();
                        }
                    }
                } catch (e) {
                    console.error(e);
                } finally {
                    this.tips.value = '';
                }
            });
        }
    }

    /**
     * 初始化文件列表
     */
    initFileList() {
        if (this.fileList) {
            this.fileList.dirs = [];
            this.fileList.files = [];
            this.fileList.category = {
                pdf: [],
                excel: [],
                image: [],
                video: [],
                audio: [],
                other: [],
            };
        } else {
            this.fileList = reactive({
                dirs: [],
                files: [],
                category: {
                    pdf: [],
                    excel: [],
                    image: [],
                    video: [],
                    audio: [],
                    other: [],
                },
            });
        }
    }

    /**
     * 初始化选择的文件
     */
    initSelectFiles() {
        if (this.selectFiles) {
            this.selectFiles.video = [];
        } else {
            this.selectFiles = reactive({
                video: [],
            });
        }
    }

    /**
     * 获取所有选择的文件
     */
    getAllSelectFiles() {
        return [...this.selectFiles.video];
    }
}
